package org.zwy.gradetrack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zwy.gradetrack.entity.RolePermission;
import org.zwy.gradetrack.mapper.RolePermissionMapper;
import org.zwy.gradetrack.service.RolePermissionService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色权限关联服务实现类
 */
@Service
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements RolePermissionService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignPermissions(Long roleId, List<Long> permissionIds) {
        // 先删除原有的权限关联
        removeAllPermissions(roleId);
        
        // 如果没有新的权限，直接返回成功
        if (permissionIds == null || permissionIds.isEmpty()) {
            return true;
        }
        
        // 创建新的权限关联
        List<RolePermission> rolePermissions = permissionIds.stream()
            .map(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                return rolePermission;
            })
            .collect(Collectors.toList());
        
        return saveBatch(rolePermissions);
    }

    @Override
    public List<Long> getPermissionIdsByRoleId(Long roleId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId)
               .select(RolePermission::getPermissionId);
        
        return list(wrapper).stream()
            .map(RolePermission::getPermissionId)
            .collect(Collectors.toList());
    }

    @Override
    public List<RolePermission> getPermissionsByRoleId(Long roleId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        return list(wrapper);
    }

    @Override
    public boolean hasPermission(Long roleId, Long permissionId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId)
               .eq(RolePermission::getPermissionId, permissionId);
        return count(wrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAllPermissions(Long roleId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        return remove(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<RolePermission> rolePermissions) {
        if (rolePermissions == null || rolePermissions.isEmpty()) {
            return false;
        }
        return super.saveBatch(rolePermissions);
    }
    
    @Override
    public Map<Long, List<Long>> getPermissionIdsByRoleIds(List<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            return Collections.emptyMap();
        }
        
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RolePermission::getRoleId, roleIds);
        
        List<RolePermission> rolePermissions = list(wrapper);
        
        return rolePermissions.stream()
            .collect(Collectors.groupingBy(
                RolePermission::getRoleId,
                Collectors.mapping(RolePermission::getPermissionId, Collectors.toList())
            ));
    }
    
    @Override
    public Map<Long, Boolean> hasPermissions(List<Long> roleIds, Long permissionId) {
        if (roleIds == null || roleIds.isEmpty() || permissionId == null) {
            return Collections.emptyMap();
        }
        
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RolePermission::getRoleId, roleIds)
               .eq(RolePermission::getPermissionId, permissionId);
        
        List<RolePermission> rolePermissions = list(wrapper);
        Set<Long> roleIdsWithPermission = rolePermissions.stream()
            .map(RolePermission::getRoleId)
            .collect(Collectors.toSet());
        
        return roleIds.stream()
            .collect(Collectors.toMap(
                roleId -> roleId,
                roleIdsWithPermission::contains
            ));
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAllPermissionsBatch(List<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            return true;
        }
        
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RolePermission::getRoleId, roleIds);
        return remove(wrapper);
    }
    
    @Override
    public List<Long> getRoleIdsByPermissionId(Long permissionId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getPermissionId, permissionId)
               .select(RolePermission::getRoleId);
        
        return list(wrapper).stream()
            .map(RolePermission::getRoleId)
            .collect(Collectors.toList());
    }
    
    @Override
    public Map<Long, List<Long>> getRoleIdsByPermissionIds(List<Long> permissionIds) {
        if (permissionIds == null || permissionIds.isEmpty()) {
            return Collections.emptyMap();
        }
        
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RolePermission::getPermissionId, permissionIds);
        
        List<RolePermission> rolePermissions = list(wrapper);
        
        return rolePermissions.stream()
            .collect(Collectors.groupingBy(
                RolePermission::getPermissionId,
                Collectors.mapping(RolePermission::getRoleId, Collectors.toList())
            ));
    }
} 